﻿using Onshi.POS.Modelo.Entidades;
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Text;

namespace Onshi.POS.Modelo.Objectos
{
    public class ArticuloTipoSeleccion
    {
        #region Metodos

        private static List<ArticuloExistencia> Numerar(List<ArticuloExistencia> listado)
        {
            for (Int32 i = 0; i < listado.Count; i++)
                listado[i].Id = i + 1;
            return listado;
        }

        private static List<ArticuloExistencia> AgregarVariante(List<ArticuloExistencia> listado, ArticuloVariante variante)
        {
            var listadoFinal = new List<ArticuloExistencia>();
            foreach (var valor in variante.Valores)
            {
                var listadoTemporal = new List<ArticuloExistencia>();
                foreach (var item in listado)
                {
                    var exis = new ArticuloExistencia();
                    exis.VariantesDetalles = new List<ArticuloVarianteDetalle>();
                    foreach (var item2 in item.VariantesDetalles)
                        exis.VariantesDetalles.Add(item2);
                    listadoTemporal.Add(exis);
                }
                if (listadoTemporal.Count > 0)
                    foreach (var existencia in listadoTemporal)
                        existencia.VariantesDetalles.Add(valor);
                else
                {
                    var existencia = new ArticuloExistencia();
                    existencia.VariantesDetalles = new List<ArticuloVarianteDetalle>();
                    existencia.VariantesDetalles.Add(valor);
                    listadoFinal.Add(existencia);
                }
                listadoFinal.AddRange(listadoTemporal);
            }
            return listadoFinal;
        }

        private static List<ArticuloExistencia> AgregarUbicaciones(List<ArticuloExistencia> listado, List<Ubicacion> ubicaciones)
        {
            var listadoFinal = new List<ArticuloExistencia>();
            foreach (var ubicacion in ubicaciones)
            {
                var listadoTemporal = new List<ArticuloExistencia>();
                if (listado.Count > 0)
                {
                    foreach (var item in listado)
                    {
                        var existencia = new ArticuloExistencia();
                        existencia.VariantesDetalles = new List<ArticuloVarianteDetalle>();
                        foreach (var item2 in item.VariantesDetalles)
                            existencia.VariantesDetalles.Add(item2);
                        existencia.Ubicacion = ubicacion;
                        listadoTemporal.Add(existencia);
                    }
                }
                else
                {
                    var existencia = new ArticuloExistencia();
                    existencia.VariantesDetalles = new List<ArticuloVarianteDetalle>();
                    existencia.Ubicacion = ubicacion;
                    listadoTemporal.Add(existencia);
                }
                listadoFinal.AddRange(listadoTemporal);
            }
            return listadoFinal;
        }

        public static Boolean MismasVariantes(List<ArticuloVarianteDetalle> variantesA, List<ArticuloVarianteDetalle> variantesB)
        {
            var mismas = true;
            if (variantesA.Count != variantesB.Count)
                mismas = false;
            if (mismas)
                foreach (var item in variantesA)
                    if (mismas)
                        mismas = variantesB.Exists(x => x.Valor == item.Valor && x.Variante.Id == item.Variante.Id);
            return mismas;
        }

        private static List<ArticuloExistencia> AgregarExistencias(List<ArticuloExistencia> listado, List<ArticuloExistencia> existencias)
        {
            foreach (var item in listado)
                if (item.Ubicacion == null)
                {
                    foreach (var existencia in existencias)
                        if (!existencia.EstaEliminado)
                            if (MismasVariantes(item.VariantesDetalles, existencia.VariantesDetalles))
                                item.Cantidad += existencia.Cantidad;
                }
                else
                    foreach (var existencia in existencias)
                        if (!existencia.EstaEliminado)
                            if (item.Ubicacion.Id == existencia.Ubicacion.Id)
                                if (MismasVariantes(item.VariantesDetalles, existencia.VariantesDetalles))
                                    item.Cantidad += existencia.Cantidad;
            return listado;
        }

        public static DataTable GenerarTabla(List<ArticuloExistencia> listado, Boolean conCantidades, Boolean conUbicaciones)
        {
            var columnasExtras = 1;
            var dt = new DataTable();
            dt.Columns.Add("Id", typeof(Int32));
            if (conCantidades)
            {
                dt.Columns.Add("Cantidad", typeof(Int32));
                columnasExtras++;
            }
            if (conUbicaciones)
            {
                dt.Columns.Add("Ubicacion", typeof(String));
                columnasExtras++;
            }

            if (listado != null && listado.Count > 0 && listado.FirstOrDefault() != null)
            {
                for (Int32 i = 1; i <= listado.First().VariantesDetalles.Count; i++)
                    dt.Columns.Add(String.Format("Variante{0}", i), typeof(String));

                for (Int32 i = 0; i < listado.Count; i++)
                {
                    if (conCantidades & conUbicaciones)
                        dt.Rows.Add(listado[i].Id, listado[i].Cantidad, listado[i].Ubicacion.Nombre);
                    else if (conCantidades)
                        dt.Rows.Add(listado[i].Id, listado[i].Cantidad);
                    else
                        dt.Rows.Add(listado[i].Id, listado[i].Ubicacion.Nombre);

                    for (Int32 variante = 0; variante < listado[i].VariantesDetalles.Count; variante++)
                        dt.Rows[i][variante + columnasExtras] = listado[i].VariantesDetalles[variante].Valor;
                }
            }
            return dt;
        }

        public static List<ArticuloExistencia> GenerarListado(List<ArticuloVariante> variantes)
        {
            var listado = new List<ArticuloExistencia>();
            foreach (var item in variantes)
                listado = AgregarVariante(listado, item);
            return Numerar(listado);
        }

        public static List<ArticuloExistencia> GenerarListado(List<ArticuloVariante> variantes, List<Ubicacion> ubicaciones, List<ArticuloExistencia> existencias)
        {
            var listado = GenerarListado(variantes);
            listado = AgregarUbicaciones(listado, ubicaciones);
            listado = AgregarExistencias(listado, existencias);
            return Numerar(listado);
        }

        public static List<ArticuloExistencia> GenerarListado(List<ArticuloVariante> variantes, List<Ubicacion> ubicaciones)
        {
            var listado = GenerarListado(variantes);
            listado = AgregarUbicaciones(listado, ubicaciones);
            return Numerar(listado);
        }

        public static List<ArticuloExistencia> GenerarListado(List<ArticuloVariante> variantes, List<ArticuloExistencia> existencias)
        {
            var listado = GenerarListado(variantes);
            listado = AgregarExistencias(listado, existencias);
            return Numerar(listado);
        }

        #endregion
    }
}
